using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Windows.Markup;
using Rhizome.Bindings;
using Rhizome.Contract;
using Rhizome.Contract.Diag;
using Rhizome.Contract.Visitor;
using Rhizome.Internal;
using Rhizome.Model.Validation;

namespace Rhizome.Model
{
	[ContentProperty("Property")]
	public abstract class PropertyCriterionBase<TProperty> : CriterionBase<object>, IValidate
	{
		protected PropertyCriterionBase(string property)
			: this()
		{
			Property = property;
		}

		protected PropertyCriterionBase()
		{
		}

		/// <summary>
		/// XAML macro: Sets Binding = BindingProxy.Create(value)
		/// </summary>
		public string Property
		{
			get
			{
				var b = Binding;
				return b == null ? null : b.Property;
			}
			[DebuggerStepThrough]
			set { SetValue(BindingProperty, BindingProxy.Create(value)); }
		}

		protected BindingProxy Binding
		{
			[DebuggerStepThrough]
			get { return GetValue(BindingProperty); }
		}

		public override sealed bool Test()
		{
			var value = Binding.Value.ChangeType<TProperty>();
			return IsTrue(value);
		}

		protected abstract bool IsTrue(TProperty value);

		#region Implementation of IValidate

		public virtual IEnumerable<IValidationResult> GetValidationResults()
		{
			if (Plant == null) yield return ValidationResult.PlantIsNull;
			if (string.IsNullOrEmpty(Property)) yield return ValidationResult.PropertyNotSet;
		}

		#endregion

	}
}